package com.greateffect.littlebud.lib.views;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

import com.greateffect.littlebud.lib.R;
import com.zcs.autolayout.utils.AutoUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 饼状统计图，带有标注线，都可以自行设定其多种参数选项
 * <p/>
 * Created by ZengCS on 2019/3/19.
 */
public class PieChartView extends View {

    private TextPaint mTextPaint;
    private float mTextWidth;
    private float mTextHeight;

    /**
     * 饼图半径
     */
    private float pieChartCircleRadius = 100;

    private float textBottom;
    /**
     * 记录文字大小
     */
    private float mTextSize = 14;

    /**
     * 饼图所占矩形区域（不包括文字）
     */
    private RectF pieChartCircleRectF = new RectF();

    /**
     * 饼状图信息列表
     */
    private List<PieceDataHolder> pieceDataHolders = new ArrayList<>();

    private int defaultTextColor = 0xff666666;//默认文字的颜色
    /**
     * 标记线长度
     */
    private float markerLineLength = 30f;

    public PieChartView(Context context) {
        super(context);
        init(null, 0);
    }

    public PieChartView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public PieChartView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        // Load attributes
        final TypedArray a = getContext().obtainStyledAttributes(
                attrs, R.styleable.PieChartView, defStyle, 0);

        pieChartCircleRadius = a.getDimension(R.styleable.PieChartView_circleRadius, pieChartCircleRadius);
        mTextSize = a.getDimension(R.styleable.PieChartView_textSize, mTextSize);

        a.recycle();

        pieChartCircleRadius = AutoUtils.getPercentWidthSize((int) pieChartCircleRadius);

        // Set up a default TextPaint object
        mTextPaint = new TextPaint();
        mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextAlign(Paint.Align.LEFT);


        // Update TextPaint and text measurements from attributes
        invalidateTextPaintAndMeasurements();
    }

    private void invalidateTextPaintAndMeasurements() {

        mTextPaint.setTextSize(AutoUtils.getPercentWidthSize((int) mTextSize));

        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        mTextHeight = fontMetrics.descent - fontMetrics.ascent;
        textBottom = fontMetrics.bottom;
    }

    /**
     * 设置饼状图的半径
     *
     * @param pieChartCircleRadius 饼状图的半径（px）
     */
    public void setPieChartCircleRadius(int pieChartCircleRadius) {

        this.pieChartCircleRadius = AutoUtils.getPercentWidthSize(pieChartCircleRadius);

        invalidate();
    }

    /**
     * 设置标记线的长度
     *
     * @param markerLineLength 标记线的长度（px）
     */
    public void setMarkerLineLength(int markerLineLength) {
        this.markerLineLength = markerLineLength;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        initPieChartCircleRectF();

        drawAllSectors(canvas);

    }

    private void drawAllSectors(Canvas canvas) {
        float sum = 0f;
        for (PieceDataHolder pieceDataHolder : pieceDataHolders) {
            sum += pieceDataHolder.value;
        }
        if(sum > 0){
            float sum2 = 0f;
            for (PieceDataHolder pieceDataHolder : pieceDataHolders) {
                float startAngel = sum2 / sum * 360 - 90;
                sum2 += pieceDataHolder.value;
                float sweepAngel = pieceDataHolder.value / sum * 360;
                //旋转的角度大于0 时才绘制
                if(sweepAngel > 0){
                    drawSector(canvas, pieceDataHolder.color, startAngel, sweepAngel);
                    drawMarkerLineAndText(canvas, defaultTextColor, startAngel + sweepAngel / 2, getMarkerNew(pieceDataHolder.marker,pieceDataHolder.value/sum));
                }
            }
        }
    }

    private String getMarkerNew(String marker, float rate){
        return String.format(Locale.CHINESE,"%s%.0f%s",marker,rate*100,"%");
    }

    private void initPieChartCircleRectF() {
        pieChartCircleRectF.left = getWidth() / 2 - pieChartCircleRadius;
        pieChartCircleRectF.top = getHeight() / 2 - pieChartCircleRadius;
        pieChartCircleRectF.right = pieChartCircleRectF.left + pieChartCircleRadius * 2;
        pieChartCircleRectF.bottom = pieChartCircleRectF.top + pieChartCircleRadius * 2;
    }

    /**
     * Gets the example dimension attribute value.
     *
     * @return The example dimension attribute value.(sp)
     */
    public float getTextSize() {
        return mTextSize;
    }

    /**
     * Sets the view's text dimension attribute value. In the PieChartView view, this dimension
     * is the font size.
     *
     * @param textSize The text dimension attribute value to use.(sp)
     */
    public void setTextSize(float textSize) {
        mTextSize = textSize;
        invalidateTextPaintAndMeasurements();
    }

    /**
     * 设置饼状图要显示的数据
     *
     * @param data 列表数据
     */
    public void setData(List<PieceDataHolder> data) {

        if (data != null) {
            pieceDataHolders.clear();
            pieceDataHolders.addAll(data);
        }

        invalidate();
    }

    /**
     * 绘制扇形
     *
     * @param canvas     画布
     * @param color      要绘制扇形的颜色
     * @param startAngle 起始角度
     * @param sweepAngle 结束角度
     */
    protected void drawSector(Canvas canvas, int color, float startAngle, float sweepAngle) {

        Paint paint = new Paint();
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(color);

        canvas.drawArc(pieChartCircleRectF, startAngle, sweepAngle, true, paint);

    }

    /**
     * 绘制标注线和标记文字
     *
     * @param canvas      画布
     * @param color       标记的颜色
     * @param rotateAngel 标记线和水平相差旋转的角度
     */
    protected void drawMarkerLineAndText(Canvas canvas, int color, float rotateAngel, String text) {
        Paint paint = new Paint();
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(color);

        Path path = new Path();
        path.close();
        final float x0 = (float) (getWidth() / 2 + (pieChartCircleRadius*3/4) * Math.cos(Math.toRadians(rotateAngel)));
        final float y0 = (float) (getHeight() / 2 + (pieChartCircleRadius*3/4) * Math.sin(Math.toRadians(rotateAngel)));
        final float x = (float) (getWidth() / 2 + (markerLineLength + pieChartCircleRadius) * Math.cos(Math.toRadians(rotateAngel)));
        float y = (float) (getHeight() / 2 + (markerLineLength + pieChartCircleRadius) * Math.sin(Math.toRadians(rotateAngel)));
        //检查是否超越下面边界
        y = y > getHeight() ? getHeight()-1 : y;
        //检查是否超越上边界
        y = y <= 0 ? 1 : y;
        path.moveTo(x0,y0);
        path.lineTo(x, y);
        float textWidth = mTextPaint.measureText(text);
        float landLineX;
        if (270f > rotateAngel && rotateAngel > 90f) {
            landLineX = x - textWidth;
        } else {
            landLineX = x + textWidth;
        }
        path.lineTo(landLineX, y);
        canvas.drawPath(path, paint);

        mTextPaint.setColor(color);
        //计算文字在标线上面还是下面,默认都是在上面
        float ny = y + mTextHeight - textBottom;
        if(y > mTextHeight){
            ny -= mTextHeight;
        }
        if (270f > rotateAngel && rotateAngel > 90f) {
            canvas.drawText(text, landLineX, ny, mTextPaint);
        } else {
            canvas.drawText(text, landLineX-textWidth, ny, mTextPaint);
        }

    }

    /**
     * 饼状图每块的信息持有者
     */
    public static final class PieceDataHolder {

        /**
         * 每块扇形的值的大小
         */
        private float value;

        /**
         * 扇形的颜色
         */
        private int color;

        /**
         * 每块的标记
         */
        private String marker;


        public PieceDataHolder(float value, int color, String marker) {
            this.value = value;
            this.color = color;
            this.marker = marker;
        }
    }

}
